/*
 * @Author: qinuoyun
 * @Date:   2019-11-28 12:41:25
 * @Last Modified by:   qinuoyun
 * @Last Modified time: 2019-11-29 14:58:18
 */
import Vue from 'vue';

import vmdrag from './drag';

import add_column from './add_column';

import add_label from './add_label';

import widgets_column from '../widgets/tables/column';

import widgets_label from '../widgets/forms/label';
/**
 * 拖拽指令类
 */
class dragdrop {
  constructor() {
    /**
     * 设置ID
     * @type {[type]}
     */
    this.id = null;
    /**
     * 数据存储
     */
    this.storage = null;
    /**
     * 工具
     * @type {[type]}
     */
    this.widget = null;
    /**
     * 画布-根节点
     */
    this.canva = null;
    /**
     * 父级
     */
    this.parent = null;
    /**
     * 子集
     */
    this.subset = null;
    /**
     *  结构层
     */
    this.DOM = {};
    /**
     * 数据层
     */
    this.BOM = {};

    /**
     * 判断是否初始化
     * @type {Boolean}
     */
    this.is_initialize = false;
  }


  /**
   * 结点初始化
   * @return {[type]} [description]
   */
  initialize(object, vm) {
    for (let index in object.slot) {
      //获取子集
      let item = object.slot[index];
      //2.配置数据信息
      let level = item.regulation.level;
      let component = item.components;
      let props = {
        value: item.data
      }
      let data = {
        config: item
      };
      // let dddd =  this.getParent(vm, object.regulation.level);
      // console.log("查看",dddd);
      //3.判断设置层级
      let parent = this.getParent(vm, object.regulation.level);
      let element = parent.$el;
      let instance = this.getInstance(Vue.extend(component), props, data, parent);
      let model = element.appendChild(instance.$el);
      //4.设置操作工具
      this.handleTool(instance.$el, index, model, item);
      //5.递归循环设置
      this.initialize(item, instance);
    }
  }

  /**
   * 清空页面
   * @return {[type]} [description]
   */
  clearPage() {
    if (this.canva.el.childNodes) {
      let childs = this.canva.el.childNodes;
      for (let i = childs.length - 1; i >= 0; i--) {
        this.canva.el.removeChild(childs[i]);
      }
    }

  }

  /**
   * 设置跟节点
   */
  setRoot(component, object) {
    this.canva = {
      id: 'VM_' + component._uid,
      el: component.$el,
      component: component,
      config: object
    }
  }

  /**
   * 初次写入
   * @param {[type]} component [description]
   * @param {[type]} object    [description]
   * @param {String} type      [description]
   */
  setSelf(component, object, type = "install") {
    this.sefl = null;
    let id = 'VM_' + component._uid;

    console.log("component.$el.dataset",component.$el.dataset("slot"));
    //存储ID
    this.id = id;
    //判断是否为根节点
    if (this.canva == null) {
      this.setRoot(component, object);
    }
    //判断是否初次写入
    if (type == 'install') {
      if (!this.BOM[id]) {
        this.sefl = this.BOM[id] = {
          id: 'VM_' + component._uid,
          el: component.$el,

          component: component,
          config: object
        }
      } else {
        this.sefl = this.BOM[id];
      }
    }
    //判断为更新写入
    if (type == 'update') {
      if (id == Core.canva.id) {
        this.setRoot(component, object);
      }
      this.sefl = this.BOM[id] = {
        id: 'VM_' + component._uid,
        el: component.$el,
        component: component,
        config: object
      }

    }
  }

  /**
   * 获取当前
   * @param  {[type]} component [description]
   * @return {[type]}           [description]
   */
  getSelf(component = null) {
    this.sefl = null;
    let id = this.id;
    if (component) {
      id = 'VM_' + component._uid;
    }
    return this.sefl = this.BOM[id];
  }

  /**
   * 设置数据存储
   * @param {[type]} data [description]
   */
  setWidget(data) {
    this.widget = this.deepCopy(data.default);
  }

  /**
   * 设置数据存储
   */
  getWidget() {
    return this.widget
  }

  /**
   * 清除存储
   * @return {[type]} [description]
   */
  clearWidget() {
    this.widget = null;
  }

  /**
   * 事件绑定
   * @param {any} element  绑定dom
   * @param {any} event    事件类型
   * @param {any} listener 方法
   */
  addEvent(element, event, listener) {
    if (element.addEventListener) {
      element.addEventListener(event, listener, false);
    } else if (element.attachEvent) {
      element.attachEvent('on' + event, listener);
    } else {
      element['on' + event] = listener;
    }
  }

  /**
   * 获取实例化
   * @return {[type]} [description]
   */
  getInstance(component, props, data = {}, parent = null) {
    let instance = new component({
      propsData: props,
      parent: parent,
      data() {
        return data;
      },
      el: document.createElement('div')
    })
    return instance;
  }

  /**
   * 处理数据验证
   * @return {Boolean} [description]
   */
  isRegulation() {
    console.log("目标", this.sefl);
    console.log("溯源", this.widget);
    //目标元素
    let target = {
      name: this.sefl.config.name,
      amount: this.sefl.config.regulation.amount,
      scope: this.sefl.config.regulation.scope,
      number: this.sefl.config.slot.length
    }
    //数据源
    let source = {
      name: this.widget.name,
      amount: this.widget.regulation.amount,
      scope: this.widget.regulation.scope
    }

    if (target.number < target.amount) {
      if (target.scope[0] && target.scope[0].substring(0, 1) === '-') {
        if (target.scope.indexOf('-' + source.name) == -1) {
          return true;
        }
      } else if (target.scope[0]) {
        if (target.scope.indexOf(source.name) != -1) {
          return true;
        }
      }
    }
    return false;
  }

  /**
   * 操作元素. (component, props, data = {}, el = null, parent = null) {
   * @return {[type]} [description]
   */
  handleEvent(element) {
    //1.下节点写入数据
    this.sefl.config.slot.push(this.widget);
    let level = this.sefl.config.regulation.level;
    let index = this.sefl.config.slot.length - 1;
    //2.获取实例化
    let component = this.widget.components;
    let props = {
      value: this.widget.data
    }
    let data = {
      config: this.widget
    };
    //3.判断设置层级

    let parent = this.sefl.component;
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    let model = element.appendChild(instance.$el);
    //4.设置操作工具
    this.handleTool(instance.$el, index, model, this.widget);
  }


  /**
   * 操作元素. (component, props, data = {}, el = null, parent = null) {
   * @return {[type]} [description]
   */
  handleTool(element, index, model, widget) {
    //1.获取实例化
    let component = vmdrag;
    let props = {
      value: this.sefl.config,
      index: index
    };
    let data = {
      model: model,
      config: widget
    };

    let parent = this.canva.component;
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    //3.执行绑定添加
    element.appendChild(instance.$el);
  }

  /**
   * 添加单元格
   * @param  {[type]} element 表格组件-标签
   * @param  {[type]} config  表格组件-数据
   * @param  {[type]} vm  表格的VM结构
   * @return {[type]}         [description]
   */
  handleColumn(element, config, vm) {
    //1.获取实例化
    let component = add_column;
    let props = {
      value: config
    };
    let data = {
      config: config
    };

    let parent = this.canva.component;
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    //3.执行绑定添加
    element.appendChild(instance.$el);
    return instance.$el;
  }

  /**
   * 添加单元格
   * @param  {[type]} element 表格组件-标签
   * @param  {[type]} config  表格组件-数据
   * @param  {[type]} vm  表格的VM结构
   * @return {[type]}         [description]
   */
  handleColumnAdd(config, vm) {
    config.slot.push(widgets_column);
    console.log("widgets_column", widgets_column);
    console.log("handleColumnAdd", vm);
    //1.获取实例化
    let component = widgets_column.components;
    let props = {
      value: widgets_column.data
    };
    let data = {
      config: widgets_column
    };

    let element = vm.$children[0].$el;
    let parent = vm.$children[0]
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    //3.执行绑定添加
    element.appendChild(instance.$el);
  }



  /**
   * 添加单元格
   * @param  {[type]} element 表格组件-标签
   * @param  {[type]} config  表格组件-数据
   * @param  {[type]} vm  表格的VM结构
   * @return {[type]}         [description]
   */
  handleLabel(element, config, vm) {
    //1.获取实例化
    let component = add_label;
    let props = {
      value: config
    };
    let data = {
      config: config
    };

    let parent = this.canva.component;
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    //3.执行绑定添加
    element.appendChild(instance.$el);
    return instance.$el;
  }

  /**
   * 添加单元格
   * @param  {[type]} element 表格组件-标签
   * @param  {[type]} config  表格组件-数据
   * @param  {[type]} vm  表格的VM结构
   * @return {[type]}         [description]
   */
  handleLabelAdd(config, vm) {
    config.slot.push(widgets_label);
    // console.log("widgets_label", widgets_label);
    // console.log("handleColumnAdd", vm);
    //1.获取实例化
    let component = widgets_label.components;
    let props = {
      value: widgets_label.data
    };
    let data = {
      config: config
    };

    let element = vm.$children[0].$el;
    let parent = vm.$children[0]
    let instance = this.getInstance(Vue.extend(component), props, data, parent);
    //3.执行绑定添加
    element.appendChild(instance.$el);
  }

  /**
   * 获取父级
   * @return {[type]} [description]
   */
  getParent(vm, level) {
    if (level === false) {
      return vm;
    } else {
      console.log("执行我了");
      let cache = vm;
      for (let i in level) {
        let item = level[i];
        cache = cache.$children[item]
      }
      return cache
    }
  }

  /**
   * 获取子集
   * @return {[type]} [description]
   */
  getSubset() {

  }

  /**
   * 深度拷贝
   * @param  {[type]} obj   [description]
   * @param  {Array}  cache [description]
   * @return {[type]}       [description]
   */
  deepCopy(obj, cache = []) {
    // just return if obj is immutable value
    if (obj === null || typeof obj !== 'object') {
      return obj
    }

    // if obj is hit, it is in circular structure
    const hit = find(cache, c => c.original === obj)
    if (hit) {
      return hit.copy
    }

    const copy = Array.isArray(obj) ? [] : {}
    // put the copy into cache at first
    // because we want to refer it in recursive deepCopy
    cache.push({
      original: obj,
      copy
    })

    Object.keys(obj).forEach(key => {
      copy[key] = this.deepCopy(obj[key], cache)
    })

    return copy
  }

}

let Core = new dragdrop();

/**
 * 指令合集
 * @type {Object}
 */
let directives = {
  /**
   * 工具拖拽
   * @type {Object}
   */
  iwidget: {
    /**
     * 指令初始化
     * @type {Object}
     */
    inserted: function(el, binding, vnode) {
      //添加拖拽属性
      el.setAttribute("draggable", true);
      //添加拖拽开始事件
      Core.addEvent(el, 'dragstart', function(el) {
        Core.setWidget(binding.value)
      });
      //添加拖拽结束事件
      Core.addEvent(el, 'dragend', function(el) {
        Core.clearWidget()
      });
    }
  },
  /**
   * 拖拽放置画布
   * @type {Object}
   */
  icanva: {
    /**
     * 指令绑定
     * @type {Object}
     */
    bind: function(el, binding, vnode) {
      //阻止默认方法
      Core.addEvent(el, 'dragover', function(el) {
        el.preventDefault();
      })
    },
    /**
     * 指令初始化
     * @type {Object}
     */
    inserted: function(el, binding, vnode) {
      // 添加拖拽事件
      Core.addEvent(el, 'drop', function(event) {
        //初始化写入
        Core.setSelf(vnode.context, binding.value);
        if (Core.isRegulation()) {
          Core.handleEvent(el);
        } else {
          console.log("验证不过");
        }
        //处理冒泡问题
        event.cancelBubble = true;
        event.stopPropagation();
      })
    },
    /**
     * 数据更新
     * @type {Object}
     */
    update: function(el, binding, vnode) {
      //console.log("执行更新", vnode.context);
      //数据更新写入
      Core.setSelf(vnode.context, binding.value, 'update');
      //判断是否为新建
      if (Core.sefl.id == Core.canva.id && Core.sefl.config.slot.length == 0) {
        Core.clearPage();
        Core.is_initialize = false;
      }
      // console.log("查看", [Core.is_initialize, Core.self]);
      //用于初始化页面
      if (Core.canva.config.slot.length > 0 && Core.is_initialize == false) {
        Core.is_initialize = true;
        Core.clearPage();
        console.log("vnode.context", );
        Core.initialize(Core.canva.config, vnode.context);
      }
    }
  },
  /**
   * 新增单元格
   * @type {Object}
   */
  icolumn: {
    /**
     * 指令初始化
     * @type {Object}
     */
    inserted: function(el, binding, vnode) {
      //在DOM结构写入添加按钮
      let el2 = Core.handleColumn(el, binding.value, vnode.context);
      console.log("el2", el2);
      //Core.setSelf(vnode.context, binding.value);
      Core.addEvent(el2, 'click', function() {
        console.log("el", [el, event, binding.value, vnode.context]);
        Core.handleColumnAdd(binding.value, vnode.context)
        //处理冒泡问题
        event.cancelBubble = true;
        event.stopPropagation();

      });
    }
  },
  /**
   * 新增表单元素
   * @type {Object}
   */
  ilabel: {
    /**
     * 指令绑定
     * @type {Object}
     */
    bind: function(el, binding, vnode) {

    },
    /**
     * 指令初始化
     * @type {Object}
     */
    inserted: function(el, binding, vnode) {
      //在DOM结构写入添加按钮
      let el2 = Core.handleLabel(el, binding.value, vnode.context);
      console.log("el2", el2);
      //Core.setSelf(vnode.context, binding.value);
      Core.addEvent(el2, 'click', function() {
        console.log("el", [el, event, binding.value, vnode.context]);
        Core.handleLabelAdd(binding.value, vnode.context)
        //处理冒泡问题
        event.cancelBubble = true;
        event.stopPropagation();

      });
    },
    /**
     * 数据更新
     * @type {Object}
     */
    update: function(el, binding, vnode) {

    }
  }
}

export default directives;
